import math
import folium
from django.shortcuts import render, HttpResponseRedirect
from routing import models
from folium import plugins
import requests
import json
import re
from django.views.decorators.clickjacking import xframe_options_exempt
from django.http import JsonResponse

x_pi = 3.14159265358979324 * 3000.0 / 180.0
CENTRE = [39.9816, 116.3470]
AK = 'aAyF3QcH6QRWiPwVot0eOdGFtoi3c8Go'
save_path = 'routing/templates/'
IP = '106.39.42.254'
LOCATION = [39.9816, 116.3470]


def address2location(addr):
    url = 'http://api.map.baidu.com/geocoding/v3/?address={}&output=json&ak={}&callback=showLocation'.format(
        addr, AK)
    res = requests.get(url)
    results = json.loads(re.findall(r'\((.*?)\)', res.text)[0])
    return [results['result']['location']['lat'], results['result']['location']['lng']]


def location2address(lat, lng):
    url = 'http://api.map.baidu.com/reverse_geocoding/v3/?ak={}&output=json&coordtype=wgs84ll&location={},{}'.format(
        AK, lat, lng)
    res = requests.get(url)
    address = json.loads(res.text)['result']['formatted_address']
    return address


CURRENT_LOCATION = CENTRE
CURRENT_ADDRESS = location2address(CENTRE[0], CENTRE[1])


def bd2gd(lat_0, lng_0):
    x = lng_0 - 0.0065
    y = lat_0 - 0.006
    z = math.sqrt(x * x + y * y) - 0.00002 * math.sin(y * x_pi)
    theta = math.atan2(y, x) - 0.000003 * math.cos(x * x_pi)
    lng_1 = z * math.cos(theta)
    lat_1 = z * math.sin(theta)
    return [lat_1, lng_1]


def add_power(request):
    if request.method == 'POST' and request.POST:
        address = request.POST.get('address')
        total_number = request.POST.get('total_number')
        current_type = request.POST.get('current_type')
        ownership_type = request.POST.get('ownership_type')
        point = models.ChargingPoint(address=address, total_number=total_number, current_type=current_type,
                                     ownership_type=ownership_type)
        point.save()
    points = models.ChargingPoint.objects.all()
    return render(request, 'add_power.html', {'points': points})


def view_power(request):
    # global CENTRE
    current_location = CENTRE
    if request.method == 'POST':
        pro_id = request.POST.get("pro")
        city_id = request.POST.get("city")
        dis_id = request.POST.get("dis")
        prv = models.AreaInfo.objects.filter(id=pro_id).values('title')[0]['title']
        cty = models.AreaInfo.objects.filter(id=city_id).values('title')[0]['title']
        dst = models.AreaInfo.objects.filter(id=dis_id).values('title')[0]['title']
        current_location = bd2gd(*address2location(prv+cty+dst))
    lines = []
    with open('routing/templates/power_map.html', 'r', encoding='utf-8') as read_file:
        for line in read_file.readlines():
            if 'center' in line:
                line = f'                    center: {current_location},\n'
            lines.append(line)
    with open('routing/templates/power_map.html', 'w', encoding='utf-8') as write_file:
        write_file.write(''.join(lines))
    lines = []
    with open('routing/templates/AD_power_map.html', 'r', encoding='utf-8') as read_file:
        for line in read_file.readlines():
            if 'center' in line:
                line = f'                    center: {current_location},\n'
            lines.append(line)
    with open('routing/templates/AD_power_map.html', 'w', encoding='utf-8') as write_file:
        write_file.write(''.join(lines))
    lines = []
    with open('routing/templates/EP_power_map.html', 'r', encoding='utf-8') as read_file:
        for line in read_file.readlines():
            if 'center' in line:
                line = f'                    center: {current_location},\n'
            lines.append(line)
    with open('routing/templates/EP_power_map.html', 'w', encoding='utf-8') as write_file:
        write_file.write(''.join(lines))
    return render(request, 'view_power.html')


@xframe_options_exempt
def power_map(request):
    points = models.ChargingPoint.objects.all().values('address', 'current_type', 'ownership_type', 'total_number',
                                                       'available_number')
    points_info = [[bd2gd(*address2location(point['address'])), point['ownership_type'], point['address'],
                    point['current_type'], str(point['available_number'])+'闲/'+str(point['total_number'])] for point in points]
    clustered_map = folium.Map(CENTRE, tiles='https://webrd02.is.autonavi.com/appmaptile?lang=zh_en&size=1&scale=1'
                                             '&style=8&x={x}&y={y}&z={z}', attr='高德-中英文对照', zoom_start=12)
    clustered_markers = plugins.MarkerCluster().add_to(clustered_map)
    # for info in points_info:
    #     if info[4][-1] == '0':
    #         folium.Marker(location=info[0], popup=folium.Popup(
    #             html=folium.Html('{}4S店</br>'.format(info[2]), script=True, width=max(len(info[2]), len(info[3]))*12),
    #             parse_html=True, max_width=3000),
    #                       icon=folium.Icon(color='black', icon='star')).add_to(clustered_markers)
    #     elif info[4].split('闲/')[0] == '0':
    #         folium.Marker(location=info[0], popup=folium.Popup(
    #             html=folium.Html('{}</br>{}</br>{}</br>{}</br>'.format(info[2], info[3], info[1], info[4]), script=True,
    #                              width=max(len(info[2]), len(info[3]))*12), parse_html=True, max_width=3000),
    #                       icon=folium.Icon(color='red', icon='flash')).add_to(clustered_markers)
    #     else:
    #         folium.Marker(location=info[0], popup=folium.Popup(
    #             html=folium.Html('{}</br>{}</br>{}</br>{}</br>'.format(info[2], info[3], info[1], info[4]), script=True,
    #                              width=max(len(info[2]), len(info[3]))*12), parse_html=True, max_width=3000),
    #                       icon=folium.Icon(color='blue', icon='flash')).add_to(clustered_markers)
    # for info in points_info:
    #     if info[4][-1] == '0':
    #         pass
    #     elif info[3] == '直流桩':
    #         folium.Marker(location=info[0], popup=folium.Popup(
    #             html=folium.Html('{}</br>{}</br>{}</br>{}</br>'.format(info[2], info[3], info[1], info[4]), script=True,
    #                              width=max(len(info[2]), len(info[3]))*12), parse_html=True, max_width=3000),
    #                       icon=folium.Icon(color='orange', icon='flash')).add_to(clustered_markers)
    #     else:
    #         folium.Marker(location=info[0], popup=folium.Popup(
    #             html=folium.Html('{}</br>{}</br>{}</br>{}</br>'.format(info[2], info[3], info[1], info[4]), script=True,
    #                              width=max(len(info[2]), len(info[3]))*12), parse_html=True, max_width=3000),
    #                       icon=folium.Icon(color='red', icon='flash')).add_to(clustered_markers)
    for info in points_info:
        if info[4][-1] == '0':
            pass
        elif info[1] == '公共':
            folium.Marker(location=info[0], popup=folium.Popup(
                html=folium.Html('{}</br>{}</br>{}</br>{}</br>'.format(info[2], info[3], info[1], info[4]), script=True,
                                 width=max(len(info[2]), len(info[3]))*12), parse_html=True, max_width=3000),
                          icon=folium.Icon(color='green', icon='flash')).add_to(clustered_markers)
        else:
            folium.Marker(location=info[0], popup=folium.Popup(
                html=folium.Html('{}</br>{}</br>{}</br>{}</br>'.format(info[2], info[3], info[1], info[4]), script=True,
                                 width=max(len(info[2]), len(info[3]))*12), parse_html=True, max_width=3000),
                          icon=folium.Icon(color='blue', icon='flash')).add_to(clustered_markers)
    clustered_map.add_child(clustered_markers)
    file_path = save_path + 'EP_power_map.html'
    # clustered_map.save(file_path)
    return render(request, 'power_map.html')


@xframe_options_exempt
def AD_power_map(request):
    return render(request, 'AD_power_map.html')


@xframe_options_exempt
def EP_power_map(request):
    return render(request, 'EP_power_map.html')


def update_power(request, point_number):
    point = models.ChargingPoint.objects.get(point_number=point_number)
    if request.method == 'GET':
        return render(request, 'update_power.html', locals())
    if request.method == 'POST':
        available_number = request.POST['available_number']
        point.available_number = available_number
        point.save()
        return HttpResponseRedirect('/add_power')


def delete_power(request, point_number):
    point = models.ChargingPoint.objects.get(point_number=point_number)
    point.delete()
    return HttpResponseRedirect('/add_power')


def choose_power(request):
    global CURRENT_LOCATION, CURRENT_ADDRESS
    points = models.ChargingPoint.objects.all().values('address', 'current_type', 'ownership_type', 'total_number',
                                                       'available_number').filter(total_number__gt=0)
    powers = points[:10]
    if request.method == 'POST':
        CURRENT_ADDRESS = request.POST['address']
        CURRENT_LOCATION = address2location(CURRENT_ADDRESS)
        models.RoutePlan.objects.all().delete()
        for point in points:
            if point['total_number'] != 0:
                power_location = address2location(point['address'])
                distance, duration = routing(CURRENT_LOCATION, power_location)
                power = models.RoutePlan(address=point['address'], distance=distance, duration=duration,
                                         latitude=power_location[0], longitude=power_location[1],
                                         total_number=point['total_number'], available_number=point['available_number'],
                                         current_type=point['current_type'], ownership_type=point['ownership_type'])
                power.save()
        powers = models.RoutePlan.objects.all().order_by("duration")[:20]
    return render(request, 'choose_power.html', {'powers': powers, 'current_address': CURRENT_ADDRESS,
                                                 'current_latitude': CURRENT_LOCATION[0],
                                                 'current_longitude': CURRENT_LOCATION[1]})


def routing(origin, destination):
    url = 'http://api.map.baidu.com/directionlite/v1/driving?origin={},{}&destination={},{}&ak={}'.format(
        origin[0], origin[1], destination[0], destination[1], AK)
    res = requests.get(url)
    results = eval(res.text)
    distance = results['result']['routes'][0]['distance'] / 1000
    duration = results['result']['routes'][0]['duration'] / 60
    return distance, duration


def pro(request):
    pro_list = models.AreaInfo.objects.filter(parea__isnull=True)
    list = []
    # [[1,'北京']，[2,'天津'],....]  格式自己设计
    for item in pro_list:
        list.append([item.id, item.title])
    return JsonResponse({"data": list})   # 构造字典，让JsonResponse序列化返回json
                                         # {"data":[[],[],[],...[]]}


def city(request, id):
    city_list = models.AreaInfo.objects.filter(parea_id=id)     # parea_id 是字段
    list = []
    # [{id:1,title:北京},{id:2,title:天津},{}...{}]   格式自定义
    for item in city_list:
        list.append({"id": item.id, "title": item.title})
    return JsonResponse({"data": list})      # {"data":[{id:1,title:北京},{id:2,title:天津},{}...{}]}


